import { exec } from "child_process";
import { copyFile, existsSync, readFileSync, renameSync, writeFileSync } from "fs"
import path from "path"
import * as os from "os"
import { promisify } from "util";
import { Tools } from "./Tools"
import { helper } from "./Helper";
const exec_promisify = promisify(exec);

//游戏包名  
class _AndroidBuilder {
    buildDir: string = ""
    channelId: string = '100000';
    // private get channelRootPath(): string {
    //     return path.join(this.projectPath, "channel")
    // }
    channelCurPath: string = ""

    packageCfg?: PackageCfg;
    public async build(cfg: PackageCfg) {
        this.packageCfg = cfg;
        console.log("================================开始构建安卓工程=========================", cfg)
        this.handleChannelCfg()
        await this.buildPackage()
        this.ReNameApp();
    }

    //处理manifest
    private handleChannelCfg() {
        if (!this.packageCfg)
            return;
        console.log('#########  handleChannelCfg == > this.packageCfg ', this.packageCfg)
        const androidProjectPath = Editor.Project.path + "/native/engine/android"

        var stringsPath = path.join(androidProjectPath, "res/values/strings.xml",)
        var gradlePath = path.join(androidProjectPath, "app/build.gradle");
        var native_java = path.join(androidProjectPath, "app/src/com/cocos/game/JsbHelper.java");
        // var adjust_java = path.join(androidProjectPath, "app/src/com/cocos/game/AdjustMgr.java");
        // var bugly_java = path.join(androidProjectPath, "app/src/com/cocos/game/BuglyMgr.java"); 
        // var google_java = path.join(androidProjectPath, "app/src/com/cocos/game/GoogleLoginMgr.java");
        var grandle_property = path.join(this.buildDir, "gradle.properties");
        console.log(`_AndroidBuilder grandle_property `, grandle_property);
        //替换versionCode 替换versionName
        var content = readFileSync(gradlePath, { "encoding": "utf8" });
        content = content.replace(/versionCode \d+/, `versionCode ${this.packageCfg.versionCode}`);
        content = content.replace(/versionName ".+"/, `versionName "${this.packageCfg.versionName}"`);
        writeFileSync(gradlePath, content, { "encoding": "utf8" }); 
        //替换包名
        content = readFileSync(native_java, { "encoding": "utf8" });
        content = content.replace(
            /import\s+.*?\.R;/,
            `import ${this.packageCfg.packageName}.R;`
        );
        // 替换java中的环境变量
        content = content.replace(/public static final int ENV_TYPE = (.*?);/g
            , `public static final int ENV_TYPE = ${helper.isRelease ? 1 : 0};`);
        writeFileSync(native_java, content, { "encoding": "utf8" })

        content = readFileSync(grandle_property, { "encoding": "utf8" });
        content = content.replace(
            /APPLICATION_ID=.*/,
            `APPLICATION_ID=${this.packageCfg.packageName}`
        );
        writeFileSync(grandle_property, content, { "encoding": "utf8" })

        // content = readFileSync(adjust_java, { "encoding": "utf8" });
        // content = content.replace(
        //     /import\s+.*?\.R/,
        //     `import ${this.packageCfg.packageName}.R`
        // );
        // writeFileSync(adjust_java, content, { "encoding": "utf8" })

        // content = readFileSync(bugly_java, { "encoding": "utf8" });
        // content = content.replace(
        //     /import\s+.*?\.R/,
        //     `import ${this.packageCfg.packageName}.R`
        // );
        // writeFileSync(bugly_java, content, { "encoding": "utf8" })

        // content = readFileSync(google_java, { "encoding": "utf8" });
        // content = content.replace(
        //     /import\s+.*?\.R/,
        //     `import ${this.packageCfg.packageName}.R`
        // );
        // writeFileSync(google_java, content, { "encoding": "utf8" })
        // //替换facabookid
        content = readFileSync(stringsPath, { "encoding": "utf8" })
        content = content.replace( /<string\s+name="app_name"\s+translatable="false">.*?<\/string>/, `<string name="app_name" translatable="false">${this.packageCfg.name}</string>`)
        // content = content.replace( /<string\s+name="channel"\s+translatable="false">.*?<\/string>/, `<string name="channel" translatable="false">${this.channelId}</string>`)
        // content = content.replace( /<string\s+name="default_web_client_id"\s+translatable="false">.*?<\/string>/, `<string name="default_web_client_id" translatable="false">${this.packageCfg.googleId}</string>`)
        // content = content.replace( /<string\s+name="facebook_app_id"\s+translatable="false">.*?<\/string>/, `<string name="facebook_app_id" translatable="false">${this.packageCfg.facebookId}</string>`)
        // content = content.replace( /<string\s+name="fb_login_protocol_scheme"\s+translatable="false">.*?<\/string>/, `<string name="fb_login_protocol_scheme" translatable="false">fb${this.packageCfg.facebookId}</string>`)
        // content = content.replace( /<string\s+name="facebook_client_token"\s+translatable="false">.*?<\/string>/, `<string name="facebook_client_token" translatable="false">${this.packageCfg.facebookToken}</string>`)
        // content = content.replace( /<string\s+name="adjust_token"\s+translatable="false">.*?<\/string>/, `<string name="adjust_token" translatable="false">${this.packageCfg.AdjustId}</string>`)
        // content = content.replace( /<string\s+name="bugly_appId"\s+translatable="false">.*?<\/string>/, `<string name="bugly_appId" translatable="false">${this.packageCfg.buglyId}</string>`) 
        writeFileSync(stringsPath, content, { "encoding": "utf8" })
        console.log("=================================替换Java配置=====================================")
    }

    //处理秘钥
    private async handleKeystore(channelPath: string) {
        if (!this.packageCfg)
            return
        var keystorePath = path.join(channelPath, "../keystore")
        var keyName = this.packageCfg.packageName + this.channelId;
        if (existsSync(path.join(keystorePath, keyName))) {
            return
        }
        else {
            console.log("路径：" + keystorePath)
            var cmd = (os.type() == 'Windows_NT') ? "keystore.bat" : "keystore.sh"
            if (os.type() == 'Windows_NT')
                await exec_promisify(`"${cmd}" ${keyName}`, { cwd: `${keystorePath}`, encoding: 'utf8' });
            else{
                await exec_promisify(`${keystorePath}/${cmd} ${keyName}`, {cwd: `${keystorePath}`,encoding: 'utf8'});
            }
            console.log("生成秘钥成功： " + keyName)
        }
        var gradlePath = path.join(channelPath, "build.gradle",)
        var content: string = readFileSync(gradlePath, { "encoding": "utf8" })
        content = content.replace("APPLICATION_ID", `"${this.packageCfg.packageName}"`)
        content = content.replace("RELEASE_STORE_FILE", `"../keystore/keystores/${keyName}.keystore"`)
        content = content.replace("RELEASE_KEY_ALIAS", `"${keyName}"`)
        writeFileSync(gradlePath, content, { "encoding": "utf8" })
    }


    //开始构建
    private async buildPackage() {
        if (!this.buildDir || !existsSync(this.buildDir)) {
            console.log("请设置工程目录！！！")
            return;
        }
        console.log("开始构建安卓工程------------>")
        var cmd = (os.type() == 'Windows_NT') ? "gradlew.bat" : "gradlew"
        if(os.type() == 'Windows_NT'){
            console.log("=========>Windows  构建"+this.buildDir)
            // console.log(`${cmd} assembleRelease`);
            await exec_promisify(`${cmd} assembleRelease`, { cwd: `${this.buildDir}`, encoding: 'utf8' }).catch(err=>{
                console.error('error',err);
            });
        } else {
            console.log("=========>Mac  构建"+this.buildDir)
            await exec_promisify(`./${cmd} assembleRelease`, { cwd: `${this.buildDir}`, encoding: 'utf8'});
        }
        console.log("打包成功")
    }

    //重名名APK
    private ReNameApp() {
        if (!this.packageCfg) return;
        var apkDir = path.join(this.buildDir, "apk")
        if (!existsSync(apkDir)) {
            Tools.mkdirSync(apkDir)
        }
        const appName = helper.buildConfig.name;
        var oldApk = path.join(this.buildDir, `build/${appName}/outputs/apk/release/${appName}-release.apk`)
        // console.log("oldApk", oldApk);
        // 将Date.now()转为yyyyMMddHHmmss格式
        let dateStr = Tools.formatDateToStr();
        var newApk = path.join(apkDir, `${this.packageCfg.name}-${this.packageCfg.versionName}-${dateStr}.apk`)
        // console.log("newApk", newApk);
        renameSync(oldApk, newApk);
        Tools.delFile(oldApk)
        console.log(`APK 重命名成功  `, this.packageCfg.name)
        // this.packageCfg.versionCode++;
        helper.savePackageCfg();
        console.log("================================构建安卓工程结束=========================")
        Tools.showInExplorer(apkDir)
    }
}

export const AndroidBuilder = new _AndroidBuilder();